<template>
  <div class="LogSearch">
    <el-row :gutter="10" class="linkShowSearchCondition">
      <el-col :span="12" style="width:520px;">
        <div style="width:80px;display:inline-block;">{{$t('时间范围：')}}</div>
        <el-date-picker v-model="timeRange" type="datetimerange" @blur="clearBlur" @change="timeRangeChange" :default-value="pickerValue" :picker-options="pickerOptions" :range-separator="$t('至')" :start-placeholder="$t('开始日期')" :end-placeholder="$t('结束日期')" size='small' value-format='yyyy-MM-dd HH:mm:ss' style="margin-bottom:10px;">
        </el-date-picker>
      </el-col>
      <el-col :span="12">
        <el-button type="success" size='small' @click="seniorListData('init')" style="margin-bottom:10px;" class="senior">{{$t('高级搜索')}}</el-button>
        <!-- <el-button type="success" size='small' @click="sessionListData('init')" style="margin-bottom:10px;" class="nomalfinds">{{$t('会话搜索')}}</el-button> -->
        <el-button type="text" id="closeSearchBtn" size='small' @click="showAll = !showAll" style="margin-bottom:10px;">
          {{word}}
          <i :class="showAll ? 'el-icon-arrow-up ': 'el-icon-arrow-down'"></i>
        </el-button>
      </el-col>
    </el-row>
    <collapseTransition name="slide-fade">
      <el-row :gutter="10" class="linkShowSearchCondition" id="searchBox" v-show="showAll">
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('所属模块：')}}</div>
          <el-select v-model="record.mode" filterable clearable :placeholder="$t('请选择')" @change="logSearchExpandRecordChange" style="width:220px;margin-bottom:10px;" size='small'>
            <el-option v-for="item in modesList" :key="item.name" :label="$t(item.chinese_name)" :value="item.name">
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('级别：')}}</div>
          <el-select v-model="record.level" filterable clearable :placeholder="$t('请选择')" style="width:220px;margin-bottom:10px;" size='small'>
            <el-option v-for="(item, key) in levelList" :key="key" :label="item" :value="key">
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('源地址：')}}</div>
          <el-input v-emoji v-model="record.srcIp" style="width:220px;margin-bottom:10px;" size='small'></el-input>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('目的地址：')}}</div>
          <el-input v-emoji v-model="record.dstIp" style="width:220px;margin-bottom:10px;" size='small'></el-input>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('源端口：')}}</div>
          <el-input v-emoji v-model="record.sport" style="width:220px;margin-bottom:10px;" size='small'></el-input>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('目的端口：')}}</div>
          <el-input v-emoji v-model="record.dport" style="width:220px;margin-bottom:10px;" size='small'></el-input>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('事件类型：')}}</div>
          <el-select v-model="record.eventType" filterable clearable :placeholder="$t('请选择')" @change="logSearchExpandRecordChange" style="width:220px;margin-bottom:10px;" size='small'>
            <el-option v-for="item in eventTypeList" :key="item" :label="item" :value="item">
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('事件动作：')}}</div>
          <el-select v-model="record.eventAction" filterable clearable :placeholder="$t('请选择')" @change="logSearchExpandRecordChange" style="width:220px;margin-bottom:10px;" size='small'>
            <el-option v-for="item in eventActionList" :key="item" :label="$t('eventaction.'+item)" :value="item">
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="6" style="width:350px;">
          <div style="width:70px;display:inline-block;">{{$t('协议类型：')}}</div>
          <el-select v-model="record.l4type" filterable clearable :placeholder="$t('请选择')" style="width:220px;margin-bottom:10px;" size='small'>
            <el-option v-for="item in l4typeList" :key="item" :label="item" :value="item">
            </el-option>
          </el-select>
        </el-col>
      </el-row>
    </collapseTransition>
    <el-table ref="multipleTable" size='mini' :data="tableList" @expand-change='expandChange' :row-class-name="tableRowClassName" :expand-row-keys="expands" :row-key='getRowKey' @sort-change='sortChange' tooltip-effect="dark" style="width: 100%">
      <el-table-column type="expand" v-if="showTableNew === 'sessionSearch'">
        <template slot-scope="scope">
          <LogSearchExpand :row='scope.row' :logRecord='record' ref="logSearchExpand"></LogSearchExpand>
        </template>
      </el-table-column>
      <el-table-column prop="TIME" align='center' :label="$t('时间')" sortable='custom' :formatter="timeFormatter" min-width="150"></el-table-column>
      <el-table-column prop="MODE" align='center' :label="$t('模块')" min-width="120">
        <template slot-scope="scope">
          {{ $t(modeListShow(scope.row.MODE)) || '' }}
        </template>
      </el-table-column>
      <el-table-column prop="LEVEL" align='center' :label="$t('级别')" sortable='custom' min-width="100">
        <template slot-scope="scope">
          {{ levelList[scope.row.LEVEL] || '' }}
        </template>
      </el-table-column>
      <el-table-column prop="MSG" align='center' :label="$t('信息')" min-width="300">
        <template slot-scope="scope">
          <tooltip :copyText="scope.row.MSG" class="wid190">
          </tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="SIP" align='center' :label="$t('源地址')" min-width="120">
        <template slot-scope="scope">
          <tooltip :copyText="scope.row.SIP" class="wid190">
          </tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="DIP" align='center' :label="$t('目的地址')" min-width="120">
        <template slot-scope="scope">
          <tooltip :copyText="scope.row.DIP" class="wid190">
          </tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="SPORT" align='center' :label="$t('源端口')" min-width="100"></el-table-column>
      <el-table-column prop="DPORT" align='center' :label="$t('目的端口')" min-width="100"></el-table-column>
      <el-table-column prop="L4TYPE" align='center' :label="$t('协议类型')" min-width="100"></el-table-column>
      <el-table-column prop="EVENT_TYPE" align='center' :label="$t('事件类型')" min-width="100">
        <template slot-scope="scope">
          <tooltip :copyText="scope.row.EVENT_TYPE || $t('其他')" class="wid190">
          </tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="EVENT_ACTION" align='center' :label="$t('事件动作')" min-width="100">
        <template slot-scope="scope">
          {{ scope.row.EVENT_ACTION?$t('eventaction.'+scope.row.EVENT_ACTION):scope.row.EVENT_ACTION }}
        </template>
      </el-table-column>
    </el-table>
    <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="record.page" :page-size="record.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
    </el-pagination>
  </div>
</template>

<script>
import { getLogSearch, sessionSearch, advancedSearch, getEvent } from '@/api/system/logData'
import LogSearchExpand from './LogSearchExpand'
import moment from 'moment'
import { getTime } from '@/api/home'
export default {
  name: 'LogSearch',
  components: {
    LogSearchExpand
  },
  data () {
    return {
      record: {
        timeRange: '',
        mode: '',
        level: '',
        srcIp: '',
        dstIp: '',
        eventType: '',
        eventAction: '',
        sport: '',
        dport: '',
        l4type: '',
        FIELD: '',
        ORDERTYPE: '',
        page: 1,
        limit: 20
      },
      recordCopy: {
        timeRange: '',
        mode: '',
        level: '',
        srcIp: '',
        dstIp: '',
        eventType: '',
        eventAction: '',
        sport: '',
        dport: '',
        l4type: '',
        FIELD: '',
        ORDERTYPE: '',
        page: 1,
        limit: 20
      },
      form: {
        timeRange: '',
        mode: '',
        level: '',
        srcIp: '',
        dstIp: '',
        eventType: '',
        eventAction: '',
        sport: '',
        dport: '',
        l4type: '',
        FIELD: '',
        ORDERTYPE: '',
        page: 1,
        limit: 20
      },
      showAll: false,
      showTableNew: '',
      timeRange: null,
      loading: false,
      total: 0,
      tableList: [],
      onIndex: null,
      expands: [],
      levelList: {
        '1': 'ERROR',
        '2': 'ALERT',
        '3': 'INFO',
        '4': 'DEBUG'
      },
      actionsList: {
        'DROP': '丢弃',
        'REJECT': '拒绝',
        'SE': '安全引擎',
        'ACCEPT': '允许'
      },
      modesList: [],
      eventTypeList: [],
      eventActionList: [],
      l4typeList: [],
      pickerMinDate: '',
      sortList: {
        'descending': 'desc',
        'ascending': 'asc'
      },
      pickerValue: [new Date().getTime() - 3600 * 1000 * 24 * 30, new Date().getTime()],
      pickerOptions: {
        onPick: (obj) => {
          if (this.pickerMinDate === '') {
            this.pickerMinDate = new Date(obj.minDate).getTime()
          } else {
            this.pickerMinDate = ''
          }
        },
        disabledDate: (time) => {
          if (this.pickerMinDate) {
            const day1 = 10 * 24 * 3600 * 1000 - 1
            let maxTime = this.pickerMinDate + day1
            let minTime = this.pickerMinDate - day1
            return time.getTime() > maxTime || time.getTime() < minTime || time.getTime() > Date.now()
          } else {
            // return time.getTime() > Date.now() + 0 * 24 * 3600 * 1000
            return time.getTime() > new Date()
          }
        },
        // disabledDate: (time) => {
        //   return time.getTime() > new Date()
        // },
        shortcuts: [{
          text: this.$t('今天'),
          onClick (picker) {
            const end = new Date()
            const start = new Date(moment(new Date()).format('YYYY-MM-DD 00:00:00'))
            picker.$emit('pick', [start, end])
          }
        }, {
          text: this.$t('最近三天'),
          onClick (picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 3)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: this.$t('最近一周'),
          onClick (picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }]
      }
    }
  },
  computed: {
    word: function () {
      if (this.showAll === false) {
        // 对文字进行处理
        return this.$t('展开搜索')
      } else {
        return this.$t('收起搜索')
      }
    }
  },
  created () {
    getTime()
    getEvent().then(res => {
      if (res.status === 0) {
        this.eventTypeList = res.info.event_type
        this.eventActionList = res.info.event_action
        this.l4typeList = res.info.l4type
        this.modesList = res.info.mode
      }
    })
    this.listData('init')
  },
  methods: {
    handleSizeChange (val) {
      // console.log(`每页 ${val} 条`)
      this.record.limit = val
      this.form.limit = val
      this.record.page = 1
      this.form.page = 1
      if (this.showTableNew === 'advancedSearch') {
        this.seniorListData()
      } else if (this.showTableNew === 'sessionSearch') {
        this.sessionListData()
      } else {
        this.listData()
      }
    },
    handleCurrentChange (val) {
      // console.log(`当前页: ${val}`)
      this.record.page = val
      this.form.page = val
      if (this.showTableNew === 'advancedSearch') {
        this.seniorListData()
      } else if (this.showTableNew === 'sessionSearch') {
        this.sessionListData()
      } else {
        this.listData()
      }
    },
    listData () {
      getLogSearch({ FIELD: this.record.FIELD, ORDERTYPE: this.record.ORDERTYPE, page: this.record.page, limit: this.record.limit }).then(res => {
        if (res.status === 0) {
          this.tableList = res.info.data
          this.total = res.info.count
        }
      })
    },
    // 会话
    sessionListData (flag) {
      let formData = JSON.parse(JSON.stringify(this.form))
      if (flag === 'init') { // 判断是初始化还是翻页
        formData = JSON.parse(JSON.stringify(this.record))
      }
      let ruleForm = this.ruleForm(formData) // 校验函数
      if (!this.record.timeRange) {
        this.$messages.error(this.$t('请选择时间范围'))
      } else if (ruleForm) {
        this.$messages.error(this.$t(ruleForm))
      } else {
        if (flag === 'init') { // 初始化时保存数据，翻页时使用保存的数据
          this.record.page = 1
          this.form = JSON.parse(JSON.stringify(this.record))
        }
        sessionSearch(formData).then(res => {
          if (res.status === 0) {
            this.tableList = res.info.data
            this.total = res.info.count
            this.showTableNew = 'sessionSearch'
          }
        })
      }
    },
    // 高级
    seniorListData (flag) {
      let formData = JSON.parse(JSON.stringify(this.form))
      if (flag === 'init') { // 判断是初始化还是翻页
        formData = JSON.parse(JSON.stringify(this.record))
      }
      let ruleForm = this.ruleForm(formData) // 校验函数
      if (!this.record.timeRange) { // 初始化时保存数据，翻页时使用保存的数据
        this.$messages.error(this.$t('请选择时间范围'))
      } else if (ruleForm) {
        this.$messages.error(ruleForm)
      } else {
        if (flag === 'init') {
          this.record.page = 1
          this.form = JSON.parse(JSON.stringify(this.record))
        }
        advancedSearch(formData).then(res => {
          this.tableList = res.info.data
          this.total = res.info.count
          this.showTableNew = 'advancedSearch'
        })
      }
    },
    ruleForm (form) {
      let ipv4 = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
      let ipv6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
      if (form.srcIp && !ipv4.test(form.srcIp) && !ipv6.test(form.srcIp)) {
        return '源地址格式不正确'
      }
      if (form.dstIp && !ipv4.test(form.dstIp) && !ipv6.test(form.dstIp)) {
        return '目的地址格式不正确'
      }
      if (form.sport && (Number(form.sport) > 65535 || Number(form.sport) < 0 || !this.isInteger(form.sport))) {
        return '源端口格式不正确'
      }
      if (form.dport && (Number(form.dport) > 65535 || Number(form.dport) < 0 || !this.isInteger(form.dport))) {
        return '目的端口格式不正确'
      }
    },
    isInteger (value) {
      return (!isNaN(value) && (parseInt(value).toString().length === String(Number(value)).length))
    },
    timeFormatter (data) {
      return moment(new Date(data.TIME) * 1000).format('YYYY-MM-DD HH:mm:ss')
    },
    timeRangeChange () {
      if (this.timeRange && this.timeRange.length > 0) {
        if (((new Date(this.timeRange[1]).getTime() - new Date(this.timeRange[0]).getTime()) / 1000 / 3600 / 24) > 10) {
          this.$message({
            message: this.$t('最多选择10天时间范围'),
            type: 'error'
          })
          this.timeRange[1] = moment(new Date(this.timeRange[0]).getTime() + 24 * 3600 * 1000 * 10).format('YYYY-MM-DD HH:mm:ss')
        }
        this.record.timeRange = this.timeRange[0] + '~' + this.timeRange[1]
      } else {
        this.record.timeRange = ''
      }
    },
    clearBlur () {
      this.pickerMinDate = ''
    },
    sortChange (column, prop, order) {
      if (column.order) {
        this.record.FIELD = column.prop
        this.record.ORDERTYPE = this.sortList[column.order]
      } else {
        this.record.FIELD = ''
        this.record.ORDERTYPE = ''
      }
      if (this.showTableNew === 'advancedSearch') {
        this.seniorListData()
      } else if (this.showTableNew === 'sessionSearch') {
        this.sessionListData()
      } else {
        this.listData()
      }
    },
    modeListShow (mode) {
      if (this.modesList && this.modesList.length > 0) {
        return this.modesList.filter(item => item.name === mode)[0] ? this.modesList.filter(item => item.name === mode)[0].chinese_name : mode
      }
    },
    tableRowClassName ({ row, rowIndex }) {
      if (row.ID === this.onIndex) {
        return 'warning-row'
      }
      return ''
    },
    expandChange (row, expandedRows) {
      this.expands = []
      this.onIndex = null
      if (expandedRows.length > 0) {
        this.onIndex = row.ID
        this.expands.push(row.ID)
      }
    },
    getRowKey (row) {
      return row.ID
    },
    logSearchExpandRecordChange () {
      this.$refs.logSearchExpand.changeRecord(this.record)
    }
  }
}
</script>
<style lang="less" scoped>
.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.3s ease;
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateY(-10px);
  opacity: 0;
}
</style>
<style lang="less">
.LogSearch {
  .el-table .warning-row {
    background: rgb(95, 184, 120) !important;
    color: #fff;
  }
  .el-table .el-table__expanded-cell {
    background: #e6e6e6 !important;
  }
  /* 用来设置当前页面element全局table 鼠标移入某行时的背景色*/
  .el-table--enable-row-hover .el-table__body .warning-row:hover > td {
    background: rgb(95, 184, 120) !important;
  }
  .el-table--enable-row-hover .el-table__body .el-table__row:hover > td {
    color: #0033ff; /* 设置文字颜色，可以选择不设置 */
  }
}
</style>
